Skip to content

Conversation

@febo
Copy link
Collaborator

@febo febo commented Sep 17, 2025

Problem

When a precision value larger than the maximum number of digits of a type is used, an overflow occurs and leads to out-of-bounds writes. There is also an issue with the truncate limit equal to 0 when logging string values.

Solution

This PR updates the logic so the precision value is not bound to the size of the type. This allows logging an u8 value with a precision greater than the maximum number of digits that an u8 can have. The output still follows the same truncation rules, so it is limited to the size of the logging buffer.

It also fixes the truncate limit issue when logging strings by checking that the limit is greater than 0.

@febo febo requested a review from joncinque September 17, 2025 18:34
Comment on lines 211 to 212
l1.append_with_args(2u8, &[Argument::Precision(u8::MAX)]);
assert_eq!(&*l1, "0.02".as_bytes());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior is a bit surprising, but I'm having a hard time coming up with a better option.

Maybe we prepend some other character to indicate that it's been truncated at the front? So if you set u8::MAX precision, you get "*002" or "?002" or "^002".

Prepending "..." seems excessive, since it requires allocating two extra bytes that will almost never be used.

As a side note, is there a reason to not support a precision of MAX_DIGITS and return ".002"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior is a bit surprising, but I'm having a hard time coming up with a better option.

Maybe we prepend some other character to indicate that it's been truncated at the front? So if you set u8::MAX precision, you get "*002" or "?002" or "^002".

Same here. I like your idea of using a character. We already use @ when the string is truncated at the end. Perhaps ^ is a good choice, since the other kind of imply either any or missing character.

Prepending "..." seems excessive, since it requires allocating two extra bytes that will almost never be used.

As a side note, is there a reason to not support a precision of MAX_DIGITS and return ".002"?

No reason, we can do that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, I forgot about @, we can just use that if you want!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored the logic, so the precision is not restricted to the size of the type. That allows logging an u8 value with precision 9 for example. This is probably a more predictable behaviour than "truncating" the precision.

The output will still be truncated based on the size of the buffer – e.g.:

let mut logger = Logger::<4>::default();
append_with_args(u8::MAX, &[Argument::Precision(9)]);

will result in"0.0@" .

@febo febo marked this pull request as draft September 18, 2025 10:42
@febo febo force-pushed the febo/precision-cap branch from 345576b to 7365278 Compare September 19, 2025 00:24
@febo febo requested a review from joncinque September 19, 2025 10:33
@febo febo marked this pull request as ready for review September 19, 2025 10:33
@febo febo changed the title log: Add cap to precision value log: Update precision logic Sep 19, 2025
joncinque
joncinque previously approved these changes Oct 3, 2025
Copy link
Collaborator

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Only nits from my side.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great tests!

Comment on lines 189 to 190
/// The precision cannot be equal to or greater than the maximum number
/// of digits for the type. If it is, it will be set to the maximum
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: up to you if you want to specify, but it can be set to something greater, but the output will get truncated, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I removed the comment since it does not apply anymore. The output will be truncated according to the size of the buffer, so it is independent of the precision.

Copy link
Collaborator

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@febo febo merged commit a271912 into main Oct 3, 2025
11 checks passed
@febo febo deleted the febo/precision-cap branch October 3, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants